using System;
using System.Data;
using System.IO;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.ServiceObjects;
using OracleInternal.TTC;

namespace Oracle.ManagedDataAccess.Types
{
	public sealed class OracleClob : Stream, ICloneable, INullable, IDisposable
	{
		internal OracleClobImpl m_clobImpl;

		internal OracleConnection m_connection;

		private OracleCommand m_command;

		private bool m_bNotNull = true;

		private bool m_isInChunkWriteMode;

		private long m_position;

		internal bool m_bClosed;

		internal bool m_bDisposed;

		private object m_lock = new object();

		private object lockClob = new object();

		internal OracleClobImpl m_inOutClobToBeRefRefed;

		public const long MaxSize = 4294967295L;

		public new static readonly OracleClob Null = new OracleClob();

		public override bool CanRead
		{
			get
			{
				if (!m_bNotNull)
				{
					return true;
				}
				if (m_bClosed)
				{
					return false;
				}
				return true;
			}
		}

		public override bool CanSeek
		{
			get
			{
				if (!m_bNotNull)
				{
					return true;
				}
				if (m_bClosed)
				{
					return false;
				}
				return true;
			}
		}

		public override bool CanWrite
		{
			get
			{
				if (!m_bNotNull)
				{
					return false;
				}
				if (m_bClosed)
				{
					return false;
				}
				return true;
			}
		}

		public override long Length
		{
			get
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0L;
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				return m_clobImpl.GetLength() * 2;
			}
		}

		public override long Position
		{
			get
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0L;
				}
				return m_position;
			}
			set
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (m_bNotNull)
				{
					if (value < 0)
					{
						throw new ArgumentOutOfRangeException("Position");
					}
					m_position = value;
				}
			}
		}

		public bool IsNull => !m_bNotNull;

		public int OptimumChunkSize
		{
			get
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0;
				}
				if (m_clobImpl.m_optimumChunkSize != 0)
				{
					return m_clobImpl.m_optimumChunkSize;
				}
				return GetOptimumChunkSize();
			}
		}

		public OracleConnection Connection
		{
			get
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return null;
				}
				return m_connection;
			}
		}

		public bool IsEmpty
		{
			get
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (Length != 0L)
				{
					return m_clobImpl.m_isEmpty = false;
				}
				return m_clobImpl.m_isEmpty = true;
			}
		}

		public bool IsNClob => m_clobImpl.m_isNClob;

		public bool IsInChunkWriteMode
		{
			get
			{
				if (!m_bNotNull)
				{
					return false;
				}
				return m_isInChunkWriteMode;
			}
		}

		public bool IsTemporary
		{
			get
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return false;
				}
				if (m_clobImpl.m_isTemporaryLob)
				{
					return true;
				}
				return m_clobImpl.IsTemporaryLob();
			}
		}

		public string Value
		{
			get
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return string.Empty;
				}
				long position = m_position;
				m_position = 0L;
				long num = Length / 2;
				int num2 = 0;
				num2 = (int)((num < int.MaxValue) ? num : int.MaxValue);
				char[] outBuffer = new char[num2];
				m_clobImpl.Read(1L, num2, 0L, ref outBuffer);
				string result = new string(outBuffer);
				m_position = position;
				return result;
			}
		}

		public OracleClob(OracleConnection con)
			: this(con, bCaching: false, bNClob: false)
		{
		}

		public OracleClob(OracleConnection connection, bool bCaching, bool bNClob)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor);
			}
			try
			{
				if (connection == null)
				{
					GC.SuppressFinalize(this);
					throw new ArgumentNullException("connection");
				}
				if (ConnectionState.Open != connection.m_connectionState)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_CLOSED));
				}
				m_connection = connection;
				m_clobImpl = new OracleClobImpl(connection.m_oracleConnectionImpl, null, bNClob, bCaching);
				m_clobImpl.m_isTemporaryLob = true;
				if (m_connection.m_oracleConnectionImpl != null)
				{
					m_connection.m_oracleConnectionImpl.RegisterForConnectionClose(this);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor);
				}
			}
		}

		internal OracleClob(OracleConnection connection, byte[] lobLocator, bool bNClob, bool bCaching)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor);
			}
			try
			{
				m_connection = connection;
				if (OracleClobImpl.IsTemporaryLob(lobLocator))
				{
					string lobIdString = OracleClobImpl.GetLobIdString(lobLocator);
					OracleClobImpl oracleClobImpl = (OracleClobImpl)connection.m_oracleConnectionImpl.TemporaryLobReferenceGet(lobIdString);
					if (oracleClobImpl != null)
					{
						m_clobImpl = oracleClobImpl;
						m_clobImpl.AddRef();
					}
					else
					{
						m_clobImpl = new OracleClobImpl(connection.m_oracleConnectionImpl, lobLocator, bNClob, bCaching);
					}
				}
				else
				{
					m_clobImpl = new OracleClobImpl(connection.m_oracleConnectionImpl, lobLocator, bNClob, bCaching);
				}
				if (m_connection.m_oracleConnectionImpl != null)
				{
					m_connection.m_oracleConnectionImpl.RegisterForConnectionClose(this);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor);
				}
			}
		}

		internal OracleClob(OracleConnection connection, OracleClobImpl clobImpl)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor);
			}
			try
			{
				m_connection = connection;
				m_clobImpl = clobImpl;
				if (m_connection.m_oracleConnectionImpl != null)
				{
					m_connection.m_oracleConnectionImpl.RegisterForConnectionClose(this);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.ctor);
				}
			}
		}

		private OracleClob()
		{
			m_bNotNull = false;
		}

		~OracleClob()
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.dtor);
			}
			try
			{
				try
				{
					Dispose(disposing: false);
				}
				catch (Exception ex)
				{
					OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.dtor, ex);
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.dtor);
				}
			}
		}

		internal byte[] GetLobLocator()
		{
			return m_clobImpl.m_lobLocator;
		}

		internal void SetLobLocator(byte[] lobLocator, bool bTempLob)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleClob, OracleTraceFuncName.SetLobLocator);
			}
			OracleClobImpl oracleClobImpl = null;
			OracleClobImpl oracleClobImpl2 = null;
			try
			{
				if ((m_clobImpl.m_isTemporaryLob && m_clobImpl.m_doneTempLobCreate) || m_clobImpl.IsTemporaryLob())
				{
					oracleClobImpl2 = (OracleClobImpl)m_clobImpl.m_connectionImpl.TemporaryLobReferenceGet(m_clobImpl.m_lobId);
				}
				oracleClobImpl = (OracleClobImpl)m_clobImpl.m_connectionImpl.TemporaryLobReferenceGet(OracleClobImpl.GetLobIdString(lobLocator));
				if (oracleClobImpl != null)
				{
					lock (m_lock)
					{
						m_clobImpl = oracleClobImpl;
						m_clobImpl.AddRef();
					}
				}
				else
				{
					m_clobImpl = new OracleClobImpl(m_clobImpl.m_connectionImpl, lobLocator, bNClob: false);
					m_clobImpl.m_lobId = OracleClobImpl.GetLobIdString(lobLocator);
					m_clobImpl.m_isTemporaryLob = bTempLob;
					m_clobImpl.m_doneTempLobCreate = true;
					m_clobImpl.m_connectionImpl.TemporaryLobReferenceAdd(m_clobImpl.m_lobId, m_clobImpl);
				}
				if (oracleClobImpl2 != null)
				{
					m_inOutClobToBeRefRefed = oracleClobImpl2;
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleClob, OracleTraceFuncName.SetLobLocator);
				}
			}
		}

		public override void Flush()
		{
		}

		public bool IsEqual(OracleClob obj)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.IsEqual);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (obj == null)
				{
					throw new ArgumentNullException("obj");
				}
				if (!m_bNotNull || obj.IsNull)
				{
					if (!m_bNotNull && obj.IsNull)
					{
						return true;
					}
					return false;
				}
				if (obj.m_connection != m_connection)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_DIFFERENT_CONNECTIONS));
				}
				if ((obj.m_clobImpl.m_isTemporaryLob && !obj.m_clobImpl.m_doneTempLobCreate) || (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate))
				{
					return false;
				}
				if (m_clobImpl.m_lobLocator != null && obj.m_clobImpl.m_lobLocator != null && (TTCLob.IsQuasiLocator(obj.m_clobImpl.m_lobLocator) || TTCLob.IsQuasiLocator(m_clobImpl.m_lobLocator) || TTCLob.IsValueBasedLocator(obj.m_clobImpl.m_lobLocator) || TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator)))
				{
					return false;
				}
				if (m_command == null)
				{
					m_command = new OracleCommand();
				}
				m_command.Connection = m_connection;
				m_command.CommandText = "BEGIN :1 := DBMS_LOB.COMPARE(:LOB_1, :LOB_2); END;";
				int num = 0;
				m_command.CommandType = CommandType.Text;
				try
				{
					OracleParameter oracleParameter = new OracleParameter("return_value", OracleDbType.Int32, num, ParameterDirection.ReturnValue);
					oracleParameter.DbType = DbType.Int32;
					m_command.Parameters.Add(oracleParameter);
					m_command.Parameters.Add("LOB_1", OracleDbType.Clob, this, ParameterDirection.Input);
					m_command.Parameters.Add("LOB_2", OracleDbType.Clob, obj, ParameterDirection.Input);
					m_command.ExecuteNonQuery();
					num = (int)m_command.Parameters[0].Value;
				}
				finally
				{
					m_command.Parameters.Clear();
				}
				if (num == 0)
				{
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.IsEqual, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.IsEqual);
				}
			}
		}

		public long Search(byte[] val, long offset, long nth)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Search);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0L;
				}
				if (offset < 0 || offset >= uint.MaxValue)
				{
					throw new ArgumentOutOfRangeException("offset");
				}
				if (nth <= 0 || nth >= uint.MaxValue)
				{
					throw new ArgumentOutOfRangeException("nth");
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				OracleString oracleString = new OracleString(val, isUnicode: true);
				int num = ((oracleString.Length <= 0) ? 1 : oracleString.Length);
				char[] array = new char[num];
				if (oracleString.Length > 0)
				{
					oracleString.Value.CopyTo(0, array, 0, oracleString.Length);
				}
				if (array.Length * 2 > 16383)
				{
					throw new ArgumentOutOfRangeException("val");
				}
				long num2 = 0L;
				offset++;
				if (m_command == null)
				{
					m_command = new OracleCommand();
				}
				m_command.Connection = m_connection;
				m_command.CommandText = "BEGIN :1 := DBMS_LOB.INSTR(:LOB_LOC, :PATTERN, :OFFSET, :NTH); END;";
				m_command.CommandType = CommandType.Text;
				try
				{
					OracleParameter oracleParameter = new OracleParameter("return_value", OracleDbType.Int64, num2, ParameterDirection.ReturnValue);
					oracleParameter.DbType = DbType.Int64;
					m_command.Parameters.Add(oracleParameter);
					OracleDbType dbType = ((!IsNClob) ? OracleDbType.Clob : OracleDbType.NClob);
					m_command.Parameters.Add("this_clob_or_nclob", dbType, this, ParameterDirection.Input);
					m_command.Parameters.Add("pattern", OracleDbType.Varchar2, array, ParameterDirection.Input);
					m_command.Parameters.Add("this_offset", OracleDbType.Int64, offset, ParameterDirection.Input);
					m_command.Parameters.Add("occurrence", OracleDbType.Int64, nth, ParameterDirection.Input);
					m_command.ExecuteNonQuery();
					num2 = (long)m_command.Parameters[0].Value;
				}
				finally
				{
					m_command.Parameters.Clear();
				}
				return num2;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Search, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Search);
				}
			}
		}

		public long Search(char[] val, long offset, long nth)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Search);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0L;
				}
				if (val.Length * 2 > 16383)
				{
					throw new ArgumentOutOfRangeException("val");
				}
				if (offset < 0 || offset >= uint.MaxValue)
				{
					throw new ArgumentOutOfRangeException("offset");
				}
				if (nth <= 0 || nth >= uint.MaxValue)
				{
					throw new ArgumentOutOfRangeException("nth");
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				long num = 0L;
				offset++;
				if (m_command == null)
				{
					m_command = new OracleCommand();
				}
				m_command.Connection = m_connection;
				m_command.CommandText = "BEGIN :1 := DBMS_LOB.INSTR(:LOB_LOC, :PATTERN, :OFFSET, :NTH); END;";
				m_command.CommandType = CommandType.Text;
				try
				{
					OracleParameter oracleParameter = new OracleParameter("return_value", OracleDbType.Int64, num, ParameterDirection.ReturnValue);
					oracleParameter.DbType = DbType.Int64;
					m_command.Parameters.Add(oracleParameter);
					OracleDbType dbType = ((!IsNClob) ? OracleDbType.Clob : OracleDbType.NClob);
					m_command.Parameters.Add("this_clob_or_nclob", dbType, this, ParameterDirection.Input);
					OracleDbType dbType2 = ((!IsNClob) ? OracleDbType.Varchar2 : OracleDbType.NVarchar2);
					m_command.Parameters.Add("pattern", dbType2, val, ParameterDirection.Input);
					m_command.Parameters.Add("this_offset", OracleDbType.Int64, offset, ParameterDirection.Input);
					m_command.Parameters.Add("occurrence", OracleDbType.Int64, nth, ParameterDirection.Input);
					m_command.ExecuteNonQuery();
					num = (long)m_command.Parameters[0].Value;
				}
				finally
				{
					m_command.Parameters.Clear();
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Search, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Search);
				}
			}
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Seek);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0L;
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				if (origin == SeekOrigin.Begin)
				{
					m_position = offset;
				}
				if (origin == SeekOrigin.Current)
				{
					m_position += offset;
				}
				if (origin == SeekOrigin.End)
				{
					m_position = Length + offset;
				}
				return m_position;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Seek, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Seek);
				}
			}
		}

		public override void SetLength(long newLength)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.SetLength);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (newLength < 0)
				{
					throw new ArgumentOutOfRangeException("newLength");
				}
				if (!m_clobImpl.m_isTemporaryLob || m_clobImpl.m_doneTempLobCreate)
				{
					if (m_clobImpl.m_refCount > 1)
					{
						CreateDeepCopy();
					}
					m_clobImpl.SetLength(newLength);
					if (m_position > newLength * 2)
					{
						Seek(0L, SeekOrigin.End);
					}
					if (newLength == 0L)
					{
						m_clobImpl.m_isEmpty = true;
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.SetLength, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.SetLength);
				}
			}
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Read);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0;
				}
				if (offset < 0)
				{
					throw new ArgumentOutOfRangeException("offset");
				}
				if (count < 0)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (offset + count > buffer.Length)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (count == 0 || (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate))
				{
					return 0;
				}
				long num = 0L;
				num = ((m_position > 0) ? (m_position / 2 + 1) : 1);
				long num2 = 0L;
				num2 = ((count + offset > buffer.Length) ? ((buffer.Length - offset) / 2) : (count / 2));
				long num3 = m_clobImpl.Read(m_position, num, num2, offset, ref buffer);
				m_position += num3;
				return (int)num3;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Read, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Read);
				}
			}
		}

		public int Read(char[] buffer, int offset, int count)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Read);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return 0;
				}
				if (m_position % 2 != 0L)
				{
					throw new ArgumentOutOfRangeException(null, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.EVEN_VALUE_PARAM_REQUIRED));
				}
				if (offset < 0)
				{
					throw new ArgumentOutOfRangeException("offset");
				}
				if (count < 0)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (offset + count > buffer.Length)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (count == 0 || (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate))
				{
					return 0;
				}
				long num = 0L;
				num = ((m_position > 0) ? (m_position / 2 + 1) : 1);
				long num2 = 0L;
				num2 = ((count + offset > buffer.Length) ? (buffer.Length - offset) : count);
				long num3 = m_clobImpl.Read(num, num2, offset, ref buffer);
				m_position += num3 * 2;
				return (int)num3;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Read, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Read);
				}
			}
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Write);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (offset < 0)
				{
					throw new ArgumentOutOfRangeException("offset");
				}
				if (count < 0)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (offset + count > buffer.Length)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (offset % 2 != 0 || count % 2 != 0 || m_position % 2 != 0L)
				{
					throw new ArgumentOutOfRangeException(null, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.EVEN_VALUE_PARAM_REQUIRED));
				}
				if (m_clobImpl.m_lobLocator != null)
				{
					if (TTCLob.IsReadOnly(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
					}
					if (TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
					}
				}
				if (m_clobImpl.m_refCount > 1)
				{
					CreateDeepCopy();
				}
				else if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					CreateTempLob();
				}
				if (count != 0)
				{
					long num = 0L;
					num = ((m_position > 0) ? (m_position / 2 + 1) : 1);
					long num2 = 0L;
					num2 = ((count + offset > buffer.Length) ? (buffer.Length - offset) : count);
					long num3 = m_clobImpl.Write(num, m_clobImpl.m_isNClob, buffer, offset, (int)num2);
					m_position += num3 * 2;
					if (num3 != 0L)
					{
						m_clobImpl.m_isEmpty = false;
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Write, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Write);
				}
			}
		}

		public void Write(char[] buffer, int offset, int count)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Write);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (m_position % 2 != 0L)
				{
					throw new ArgumentOutOfRangeException(null, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.EVEN_VALUE_PARAM_REQUIRED));
				}
				if (offset < 0)
				{
					throw new ArgumentOutOfRangeException("offset");
				}
				if (count < 0)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (offset + count > buffer.Length)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				if (m_clobImpl.m_lobLocator != null)
				{
					if (TTCLob.IsReadOnly(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
					}
					if (TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
					}
				}
				if (m_clobImpl.m_refCount > 1)
				{
					CreateDeepCopy();
				}
				else if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					CreateTempLob();
				}
				if (count != 0)
				{
					long num = 0L;
					num = ((m_position > 0) ? (m_position / 2 + 1) : 1);
					long num2 = 0L;
					num2 = ((count + offset > buffer.Length) ? (buffer.Length - offset) : count);
					long num3 = m_clobImpl.Write(num, m_clobImpl.m_isNClob, buffer, offset, num2);
					m_position += num3 * 2;
					if (num3 != 0L)
					{
						m_clobImpl.m_isEmpty = false;
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Write, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Write);
				}
			}
		}

		public void Append(OracleClob obj)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (obj == null)
				{
					throw new ArgumentNullException("obj");
				}
				if (obj.IsNull)
				{
					throw new OracleNullValueException();
				}
				if (obj.m_connection != m_connection)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_DIFFERENT_CONNECTIONS));
				}
				if (m_clobImpl.m_lobLocator != null)
				{
					if (TTCLob.IsReadOnly(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
					}
					if (TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
					}
				}
				if (!obj.m_clobImpl.m_isTemporaryLob || obj.m_clobImpl.m_doneTempLobCreate)
				{
					if (m_clobImpl.m_refCount > 1)
					{
						CreateDeepCopy();
					}
					else if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
					{
						CreateTempLob();
					}
					m_clobImpl.Append(obj.m_clobImpl.m_lobLocator);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append);
				}
			}
		}

		public void Append(byte[] buffer, int offset, int count)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (buffer.Length == 0 || count == 0)
				{
					return;
				}
				if (offset % 2 != 0 || count % 2 != 0)
				{
					throw new ArgumentOutOfRangeException(null, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.EVEN_VALUE_PARAM_REQUIRED));
				}
				if (m_clobImpl.m_lobLocator != null)
				{
					if (TTCLob.IsReadOnly(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
					}
					if (TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
					}
				}
				if (m_clobImpl.m_refCount > 1)
				{
					CreateDeepCopy();
				}
				else if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					CreateTempLob();
				}
				long position = m_position;
				Seek(0L, SeekOrigin.End);
				Write(buffer, offset, count);
				m_position = position;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append);
				}
			}
		}

		public void Append(char[] buffer, int offset, int count)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (m_clobImpl.m_lobLocator != null)
				{
					if (TTCLob.IsReadOnly(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
					}
					if (TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
					}
				}
				if (buffer.Length != 0 && count != 0)
				{
					if (m_clobImpl.m_refCount > 1)
					{
						CreateDeepCopy();
					}
					else if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
					{
						CreateTempLob();
					}
					long position = m_position;
					Seek(0L, SeekOrigin.End);
					Write(buffer, offset, count);
					m_position = position;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Append);
				}
			}
		}

		public void BeginChunkWrite()
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.BeginChunkWrite);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (m_clobImpl.m_lobLocator != null)
				{
					if (TTCLob.IsReadOnly(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
					}
					if (TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
					}
				}
				if (!m_isInChunkWriteMode)
				{
					if (m_clobImpl.m_refCount > 1)
					{
						CreateDeepCopy();
					}
					else if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
					{
						CreateTempLob();
					}
					m_clobImpl.Open();
					m_isInChunkWriteMode = true;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.BeginChunkWrite, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.BeginChunkWrite);
				}
			}
		}

		public void EndChunkWrite()
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.EndChunkWrite);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (m_isInChunkWriteMode)
				{
					m_clobImpl.Close();
					m_isInChunkWriteMode = false;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.EndChunkWrite, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.EndChunkWrite);
				}
			}
		}

		public long Erase()
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Erase);
			}
			try
			{
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				return Erase(0L, Length / 2);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Erase, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Erase);
				}
			}
		}

		public long Erase(long offset, long amount)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Erase);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					throw new OracleNullValueException();
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				if (offset < 0)
				{
					throw new ArgumentOutOfRangeException("offset");
				}
				if (amount < 0)
				{
					throw new ArgumentOutOfRangeException("amount");
				}
				if (m_clobImpl.m_lobLocator != null)
				{
					if (TTCLob.IsReadOnly(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24823, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24823));
					}
					if (TTCLob.IsValueBasedLocator(m_clobImpl.m_lobLocator))
					{
						throw new OracleException(24822, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(24822));
					}
				}
				if (m_clobImpl.m_refCount > 1)
				{
					CreateDeepCopy();
				}
				return m_clobImpl.Erase(offset + 1, amount);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Erase, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Erase);
				}
			}
		}

		public object Clone()
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Clone);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (!m_bNotNull)
				{
					return Null;
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					CreateTempLob();
				}
				OracleClob oracleClob = new OracleClob(m_connection, m_clobImpl);
				m_clobImpl.AddRef();
				oracleClob.m_position = m_position;
				oracleClob.m_bNotNull = m_bNotNull;
				return oracleClob;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Clone, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Clone);
				}
			}
		}

		public override void Close()
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Close);
			}
			if (!m_bNotNull || m_bClosed)
			{
				return;
			}
			lock (lockClob)
			{
				if (m_bClosed)
				{
					return;
				}
				try
				{
					m_clobImpl.RelRef();
					if (m_connection != null && m_isInChunkWriteMode)
					{
						EndChunkWrite();
					}
				}
				catch (Exception ex)
				{
					if (ProviderConfig.m_bTraceLevelPublic)
					{
						Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Close, ex.ToString());
					}
				}
				finally
				{
					m_bClosed = true;
					if (m_connection != null && m_connection.m_oracleConnectionImpl != null)
					{
						m_connection.m_oracleConnectionImpl.DeregisterForConnectionClose(this);
					}
					if (!m_bDisposed)
					{
						Dispose();
					}
					if (ProviderConfig.m_bTraceLevelPublic)
					{
						Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Close);
					}
				}
			}
		}

		internal void ConnectionClose()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.ConnectionClose);
			}
			try
			{
				if (!m_bClosed)
				{
					Close();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.ConnectionClose, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.ConnectionClose);
				}
			}
		}

		public int Compare(long src_offset, OracleClob obj, long dst_offset, long amount)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Compare);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (obj == null)
				{
					throw new ArgumentNullException("obj");
				}
				if (!m_bNotNull || obj.IsNull)
				{
					if (!m_bNotNull && obj.IsNull)
					{
						return 0;
					}
					throw new OracleNullValueException();
				}
				if (obj.m_connection != m_connection)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_DIFFERENT_CONNECTIONS));
				}
				if (src_offset < 0)
				{
					throw new ArgumentOutOfRangeException("src_offset");
				}
				if (dst_offset < 0)
				{
					throw new ArgumentOutOfRangeException("dst_offset");
				}
				if (amount < 0)
				{
					throw new ArgumentOutOfRangeException("amount");
				}
				if (obj.m_clobImpl.m_isTemporaryLob && !obj.m_clobImpl.m_doneTempLobCreate && m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0;
				}
				if (obj.m_clobImpl.m_isTemporaryLob && !obj.m_clobImpl.m_doneTempLobCreate)
				{
					obj.CreateTempLob();
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					CreateTempLob();
				}
				int num = -1;
				src_offset++;
				dst_offset++;
				if (m_command == null)
				{
					m_command = new OracleCommand();
				}
				m_command.Connection = m_connection;
				m_command.CommandText = "BEGIN :1 := DBMS_LOB.COMPARE(:LOB_1, :LOB_2, :AMOUNT, :OFFSET_1, :OFFSET_2); END;";
				m_command.CommandType = CommandType.Text;
				OracleParameter oracleParameter = new OracleParameter("return_value", OracleDbType.Int32, num, ParameterDirection.ReturnValue);
				oracleParameter.DbType = DbType.Int32;
				m_command.Parameters.Add(oracleParameter);
				OracleDbType dbType = ((!obj.IsNClob) ? OracleDbType.Clob : OracleDbType.NClob);
				try
				{
					m_command.Parameters.Add("provided_clob", dbType, obj, ParameterDirection.Input);
					OracleDbType dbType2 = ((!IsNClob) ? OracleDbType.Clob : OracleDbType.NClob);
					m_command.Parameters.Add("current_clob", dbType2, this, ParameterDirection.Input);
					m_command.Parameters.Add("compare_amount", OracleDbType.Int64, amount, ParameterDirection.Input);
					m_command.Parameters.Add("src_offset", OracleDbType.Int64, src_offset, ParameterDirection.Input);
					m_command.Parameters.Add("dst_offset", OracleDbType.Int64, dst_offset, ParameterDirection.Input);
					m_command.ExecuteNonQuery();
					num = (int)m_command.Parameters[0].Value;
				}
				finally
				{
					m_command.Parameters.Clear();
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Compare, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Compare);
				}
			}
		}

		public long CopyTo(OracleClob obj)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (obj == null)
				{
					throw new ArgumentNullException();
				}
				if (!m_bNotNull || obj.IsNull)
				{
					throw new OracleNullValueException();
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				return CopyTo(0L, obj, 0L, Length / 2);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo);
				}
			}
		}

		public long CopyTo(OracleClob obj, long dst_offset)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (obj == null)
				{
					throw new ArgumentNullException("obj");
				}
				if (!m_bNotNull || obj.IsNull)
				{
					throw new OracleNullValueException();
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				return CopyTo(0L, obj, dst_offset, Length / 2);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo);
				}
			}
		}

		public long CopyTo(long src_offset, OracleClob obj, long dst_offset, long amount)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (obj == null)
				{
					throw new ArgumentNullException("obj");
				}
				if (!m_bNotNull || obj.IsNull)
				{
					throw new OracleNullValueException();
				}
				if (obj.m_connection != m_connection)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_DIFFERENT_CONNECTIONS));
				}
				if (src_offset < 0)
				{
					throw new ArgumentOutOfRangeException("src_offset");
				}
				if (dst_offset < 0)
				{
					throw new ArgumentOutOfRangeException("dst_offset");
				}
				if (amount < 0)
				{
					throw new ArgumentOutOfRangeException("amount");
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					return 0L;
				}
				if (obj.m_clobImpl.m_refCount > 1)
				{
					CreateDeepCopy();
				}
				else if (obj.m_clobImpl.m_isTemporaryLob && !obj.m_clobImpl.m_doneTempLobCreate)
				{
					obj.CreateTempLob();
				}
				src_offset++;
				dst_offset++;
				return m_clobImpl.CopyTo(obj.m_clobImpl.m_lobLocator, src_offset, dst_offset, amount);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.CopyTo);
				}
			}
		}

		public new void Dispose()
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Dispose);
			}
			try
			{
				Dispose(disposing: true);
			}
			catch (Exception ex)
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Dispose, ex.ToString());
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Dispose);
				}
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.Dispose);
			}
			if (m_bDisposed)
			{
				return;
			}
			lock (lockClob)
			{
				if (m_bDisposed)
				{
					return;
				}
				try
				{
					if (!m_bNotNull)
					{
						return;
					}
					m_bDisposed = true;
					if (!m_bClosed)
					{
						Close();
					}
					if (disposing)
					{
						if (m_command != null)
						{
							m_command.Dispose();
							m_command = null;
						}
						m_connection = null;
					}
				}
				catch (Exception ex)
				{
					OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.Dispose, ex);
				}
				finally
				{
					GC.SuppressFinalize(this);
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.Dispose);
					}
				}
			}
		}

		internal void CreateTempLob()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.CreateTempLob);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					m_clobImpl.CreateTemporaryLob();
					m_clobImpl.m_doneTempLobCreate = true;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.CreateTempLob, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.CreateTempLob);
				}
			}
		}

		internal int GetOptimumChunkSize()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.GetOptimumChunkSize);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				if (m_clobImpl.m_isTemporaryLob && !m_clobImpl.m_doneTempLobCreate)
				{
					CreateTempLob();
				}
				m_clobImpl.m_optimumChunkSize = (int)m_clobImpl.GetChunkSize() * 2;
				return m_clobImpl.m_optimumChunkSize;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.GetOptimumChunkSize, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.GetOptimumChunkSize);
				}
			}
		}

		internal void CreateDeepCopy()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.OracleClob, OracleTraceFuncName.CreateDeepCopy);
			}
			try
			{
				if (m_bClosed)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.OBJECT_CLOSED));
				}
				OracleClobImpl clobImpl = m_clobImpl;
				if (IsTemporary)
				{
					m_clobImpl = new OracleClobImpl(m_connection.m_oracleConnectionImpl, null, clobImpl.m_isNClob, clobImpl.m_bCache);
					m_clobImpl.m_isTemporaryLob = true;
					CreateTempLob();
					clobImpl.CopyTo(m_clobImpl.m_lobLocator, 1L, 1L, clobImpl.GetLength());
				}
				else
				{
					byte[] array = new byte[m_clobImpl.m_lobLocator.Length];
					Array.Copy(m_clobImpl.m_lobLocator, array, array.Length);
					m_clobImpl = new OracleClobImpl(m_connection.m_oracleConnectionImpl, array, clobImpl.m_isNClob, clobImpl.m_bCache);
					m_clobImpl.m_isTemporaryLob = false;
				}
				clobImpl.RelRef();
				clobImpl = null;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.OracleClob, OracleTraceFuncName.CreateDeepCopy, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.OracleClob, OracleTraceFuncName.CreateDeepCopy);
				}
			}
		}
	}
}
